Micron Document
Fox's Git Mirrors


Displaying Raw • Download

pkg/interfaces/SCAFFOLD 61af5556362c8bdf7c09a1c01bc84f81629f281b (61af5556) Text, 6.79 KB

Interface scaffold for Reticulum-Go
===================================

Use this file to add a new network interface under pkg/interfaces/.
Follow an existing driver for patterns. Prefer UDP, TCP, or Pipe as templates.

Authoritative docs and contracts
--------------------------------

docs/en/interfaces.md
pkg/interfaces/interface.go package Interface embeds common.NetworkInterface
pkg/common/interfaces.go NetworkInterface contract
pkg/common/config.go InterfaceConfig fields
pkg/interfaces/fromconfig.go type switch factory
pkg/interfaces/plugin.go external / pipe plugins
pkg/interfaces/reconnect.go client reconnect helper
COMPATIBILITY.md Python interop status

Choose how the interface is delivered
-------------------------------------

1. In-tree driver (most common)
- New type in pkg/interfaces
- Wired through NewFromConfigWithContext
- Documented in docs/en/interfaces.md and COMPATIBILITY.md

2. External plugin (no Go rebuild for operators)
- RegisterExternalFactory for embedders
- Or {config_dir}/interfaces/{Type}.json manifest (driver pipe)
- Or executable {config_dir}/interfaces/{Type} as PipeInterface command
- See docs/en/interfaces.md External interface plugins

Do not invent a parallel packet path around Transport. Interfaces hand
raw RNS packets to the packet callback. Framing and IFAC stay on the
interface boundary.

Packet paths (must match)
-------------------------

Inbound:

wire bytes -> ProcessIncoming -> IFAC unmask -> packetCallback -> Transport

Outbound:

Transport -> Send -> IFAC mask -> ProcessOutgoing -> wire

BaseInterface.Send already applies IFAC outbound and updates TX stats.
Concrete types override ProcessOutgoing to write the medium.
ProcessIncoming on BaseInterface applies IFAC inbound then calls the callback.
Never call BaseInterface.ProcessOutgoing for real traffic (it fails loud).

Suggested file layout
---------------------

pkg/interfaces/<name>.go main type, Start, Stop, Send path
pkg/interfaces/<name>_test.go unit tests
pkg/interfaces/<name>_fuzz_test.go optional fuzz
pkg/interfaces/<name>_race_test.go optional race-focused tests
pkg/interfaces/<name>_stub.go build-tagged stub when unsupported
pkg/interfaces/<name>_<os>.go OS-specific helpers when needed
tests/interop/<name>_live_test.go optional live interop (gated)

Reuse existing helpers before inventing new ones:

BaseInterface embedding
reconnectDriver for dial clients
HDLC helpers (tcp / pipe / serial patterns)
ConnectivityNotifier hooks for up/down
NormalizeMaxReconnectTries

Required implementation checklist
---------------------------------

Embed and identity
- Embed BaseInterface (value, not pointer copy after use)
- Set Name, Type, Enabled via NewBaseInterface
- Set Mode from config (full default)
- Honor ReceiveOnly / outgoing = no via SetOutgoingAllowed

Lifecycle
- Start() opens resources, sets Online, starts read loops
- Stop() and Detach() close cleanly, idempotent where practical
- Enable / Disable update Enabled and Online consistently
- No goroutine leaks after Stop (tests often use leak checks)

IO
- ProcessOutgoing writes framed or raw bytes to the medium
- Inbound path feeds ProcessIncoming (or equivalent that ends there)
- Respect MTU and bitrate when the medium has limits
- Apply IFAC only through the BaseInterface Send / ProcessIncoming path

Config factory
- Add case in NewFromConfigWithContext for the config type string
- Map InterfaceConfig fields (do not invent parallel config structs
unless the type needs a dedicated constructor args struct)
- Add type to any post-create switch that applies common options
(mode, IFAC, announce caps, ingress control) if required by that path
- Unknown types fall through to loadExternalInterface

Interop and docs
- If matching a Python RNS interface, document keys and framing interop
- If Go-only, say so in docs/en/interfaces.md (see QUIC, WebTransport)
- Update COMPATIBILITY.md status row
- Add a config example to docs/en/interfaces.md

Config type naming
------------------

Config \\`type\\` strings are public. Match Python names when implementing a
Python counterpart (UDPInterface, TCPClientInterface, ...).

Go-only types still use the *Interface suffix for consistency.

Modes and discovery
-------------------

Modes are wire values in pkg/common (full through internal).
gateway / roaming / internal participate in unknown-path discovery.
recursive_prs = yes forces discovery on any mode.
announces_from_internal = no blocks rebroadcast from internal next hops.

Reconnect clients
-----------------

For dial-style clients, reuse reconnect.go:

max_reconnect_tries <= 0 means unlimited
positive values cap attempts
SetConnectivityHooks when the daemon should see down/up
TCP clients may SetTunnelSynth for tunnel re-synthesis on reconnect

Platform and build tags
-----------------------

If the medium is unavailable on some GOOS or WASM:

- Provide a stub file with build tags that returns a clear error
- Document platform limits in docs/en/interfaces.md
- Keep NewFromConfig wired so config parse still names the type

Reference drivers
-----------------

Simple datagram: udp.go
Stream + HDLC: tcp.go, pipe.go, serial.go
Discovery: auto.go
Reconnect client: tcp.go + reconnect.go
Plugin path: plugin.go, pipe.go
Shared instance: local.go, pkg/sharedinstance
Go-only modern: quic.go, webtransport.go, https.go, vsock.go

Tests to include
----------------

Minimum
- Construct from InterfaceConfig via NewFromConfig
- Start / Stop without leak
- Send while receive-only returns error
- ProcessOutgoing / inbound callback round-trip with a fake peer or loopback

Stronger
- IFAC mask/unmask drop path
- Reconnect success and exhausted paths
- Race test under -race
- Fuzz framing decoder if you add a parser
- Live interop behind RUN_LIVE_INTEROP=1 or type-specific env

Acceptance criteria
-------------------

1. Implements common.NetworkInterface via package Interface
2. Wired in fromconfig.go (or documented as plugin-only)
3. No BaseInterface.ProcessOutgoing used as real transmit
4. Start/Stop clean under unit tests
5. docs/en/interfaces.md section with config example
6. COMPATIBILITY.md updated when Python interop is claimed or deferred

What not to do
--------------

- Bypass Transport with a second mesh stack
- Hold or copy BaseInterface by value after mutex use
- Execute arbitrary Python plugins in-process (use pipe or RegisterExternalFactory)
- Expose a new public Control API just to carry underlay bytes
)

Served by rngit 1.5.2 - Generated in 0.08s